package com.dongjiantong.app.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dongjiantong.app.handler.SessionsModel;
import com.dongjiantong.biz.model.DrugStore;
import com.dongjiantong.biz.service.DrugStoreService;
import com.dongjiantong.common.exceptions.HttpCode;
import com.dongjiantong.common.exceptions.OPServerException;
import com.dongjiantong.common.model.CacheTime;
import com.dongjiantong.common.model.Response;
import com.dongjiantong.common.model.RoleModel;
import com.dongjiantong.common.redis.RedisUtil;
import com.dongjiantong.common.utils.MD5Util;
import com.dongjiantong.common.utils.StringUtil;
import com.dongjiantong.common.utils.WebUtil;
import com.dongjiantong.common.web.sso.LoginToken;
import com.dongjiantong.openplatform.annotations.OpenBean;
import com.dongjiantong.openplatform.annotations.OpenMethod;
import com.dongjiantong.sys.model.AnimalType;
import com.dongjiantong.sys.model.DicData;
import com.dongjiantong.sys.model.DicIllness;
import com.dongjiantong.sys.model.DicUnit;
import com.dongjiantong.sys.service.AnimalTypeService;
import com.dongjiantong.sys.service.DicDataService;
import com.dongjiantong.sys.service.DicIllnessService;
import com.dongjiantong.sys.service.DicUnitService;
import com.dongjiantong.user.enums.UserEnum;
import com.dongjiantong.user.model.*;
import com.dongjiantong.user.service.*;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.*;

/**
 * APP登录
 * Created by cao on 2017/11/8.
 */
@Slf4j
@OpenBean
public class LoginController {

    @Reference(version = "1.0.0")
    public MzUserService mzUserService;
    @Reference(version = "1.0.0")
    public RoleAppUserService roleAppUserService;
    @Reference(version = "1.0.0")
    public LogsUserLoginService logsUserLoginService;
    @Reference(version = "1.0.0")
    public OrganizationUserService organizationUserService;
    @Reference(version = "1.0.0")
    public SSOLoginService ssoLoginService;
    @Reference(version = "1.0.0")
    public OrganizationService organizationService;
    @Reference(version = "1.0.0")
    public FarmsUserService farmsUserService;
    @Value("${dongjiantong.dicver}")
    private Integer dicVersion;
    @Reference(version = "1.0.0")
    public DicDataService dicDataService;
    @Reference(version = "1.0.3")
    private AnimalTypeService animalTypeService;
    @Reference(version = "1.0.0")
    private DicUnitService dicUnitService;
    @Reference(version = "1.0.0")
    private DicIllnessService dicIllnessService;
    @Reference(version = "1.0.0")
    private DrugStoreService drugStoreService;


    @OpenMethod(key = "get.session.id", paramNames = {"key"}, httpMethods = RequestMethod.GET)
    public Response<Map<String, String>> getSessionId(String key) {
        if (StringUtil.isEmpty(key)) {
            throw new OPServerException(HttpCode.BAD_REQUEST, "设备Id不能为空");
        }
        return Response.ok(ImmutableMap.of("sessionId", WebUtil.generateId(key)));
    }

    @OpenMethod(
            key = "app.user.login",
            paramNames = {"userName", "password", "sid", "deviceId", "deviceName", "deviceVer"},
            httpMethods = RequestMethod.POST
    )
    public Response<LoginToken> Login(String userName, String password, String sid,
                                      String deviceId, String deviceName, String deviceVer) {

        if (StringUtil.isEmpty(userName)) {
            throw new OPServerException(HttpCode.BAD_REQUEST, "用户名不能为空");
        }
        if (StringUtil.isEmpty(password)) {
            throw new OPServerException(HttpCode.BAD_REQUEST, "密码不能为空");
        }
        if (StringUtil.isEmpty(sid)) {
            throw new OPServerException(HttpCode.BAD_REQUEST, "sessionId不能为空");
        }

        // 用户名密码登录

        MzUser mzUser = doLogin(userName, password, deviceId, deviceName, deviceVer);


        // 登录成功记录 session
        Map<String, Object> sessionContext = Maps.newHashMap();
        sessionContext.put(SessionsModel.USER_ID, mzUser.getId());
        if (StringUtils.hasText(deviceId)) {
            sessionContext.put(SessionsModel.DEVICE_ID, deviceId);
        }

        String sessionKey = SessionsModel.TOKEN_PREFIX + ":" + sid;
        RedisUtil.setEX(sessionKey, sessionContext, CacheTime.ONE_SHORTDAY.getTime());


        //APP角色
        List<RoleAppUser> roleAppUserList = roleAppUserService.queryRoleAppByUserId(mzUser.getId());

        List<RoleModel> roleModelList = Lists.newArrayList();
        RoleModel roleModel;
        for (RoleAppUser roleAppUser : roleAppUserList) {

            roleModel = new RoleModel();
            roleModel.setRoleCode(roleAppUser.getAppRole());
            roleModel.setRoleName(roleAppUser.getAppRoleName());

            roleModelList.add(roleModel);
        }


        // 返回登录的凭证
        LoginToken loginInfo = new LoginToken();
        loginInfo.setUserId(mzUser.getId());
        loginInfo.setRealName(mzUser.getRealname());
        loginInfo.setMobile(mzUser.getMobile());
        loginInfo.setAppRole(roleModelList);
        loginInfo.setExpiredAt(DateTime.now().plusSeconds(CacheTime.ONE_SHORTDAY.getTime())
                .toString(DateTimeFormat.forPattern("yyyyMMddHHmmss")));
        loginInfo.setSessionId(sid);
        loginInfo.setDeviceId(deviceId);
        loginInfo.setDicver(dicVersion);

        return Response.ok(loginInfo);


    }


    private MzUser doLogin(String userName, String password, String deviceId, String deviceName, String deviceVer) {

        Response<MzUser> mzUserResponse = mzUserService.checkLogin(userName, password, UserEnum.LOGIN_APP);

        if (!mzUserResponse.isSuccess()) {
            throw new OPServerException(HttpCode.LOGIN_FAIL, mzUserResponse.getMessage());
        }

        //记录登录日志
        LogsUserLogin logsUserLogin = new LogsUserLogin();
        logsUserLogin.setUserId(mzUserResponse.getResult().getId());
        logsUserLogin.setLoginTime(new Date());
        logsUserLogin.setLoginIp(WebUtil.clientIp());
        logsUserLogin.setLoginArea(WebUtil.getAreaByIP(WebUtil.clientIp()));
        logsUserLogin.setLoginFrom(UserEnum.LOGIN_APP.getCode());
        logsUserLogin.setLoginDeviceId(deviceId);
        logsUserLogin.setLoginDeviceName(deviceName);
        logsUserLogin.setLoginDeviceVer(deviceVer);

        logsUserLoginService.insert(logsUserLogin);


        return mzUserResponse.getResult();

    }

//    public Response<LoginToken> doLogin(String userName, String password, String deviceId)
//    {
//
//
//        if (StringUtil.isEmpty(userName)) {
//            throw new OPServerException(HttpCode.BAD_REQUEST,"用户名不能为空");
//        }
//        if (StringUtil.isEmpty(password)) {
//            throw new OPServerException(HttpCode.BAD_REQUEST,"登录密码不能为空");
//        }
//        if (StringUtil.isEmpty(deviceId)) {
//            throw new OPServerException(HttpCode.BAD_REQUEST,"设备Id不能为空");
//        }
//
//       return ssoLoginService.doLogin(userName,password,1);
//
////        //登录不成功
////        if(!result.isSuccess())
////        {
////            return Response.fail(HttpCode.LOGIN_FAIL,result.getMessage());
////        }
////
////        LoginToken loginToken = new LoginToken();
////
////        //取角色
////        //loginToken.
////        return null;
//    }

    /**
     * 获取字典
     *
     * @return
     */
    @OpenMethod(key = "get.sys.getDictionary", paramNames = {}, httpMethods = RequestMethod.GET)
    public Response<Map> getDictionary() {
        DicData d = new DicData();
        d.setDeleteFlag(1);
        List<DicData> dicDataList = dicDataService.select(d);

        Map<String, Map> resultMap = new HashMap<String, Map>();

        try {
            for (DicData dicData : dicDataList) {

                if (resultMap.containsKey(dicData.getDicGroup())) {//map中异常批次已存在，将该数据存放到同一个key（key存放的是异常批次）的map中

                    resultMap.get(dicData.getDicGroup()).put(dicData.getDicValue(), dicData.getDicName());
                } else {//map中不存在，新建key，用来存放数据
                    Map map = new HashMap();
                    map.put(dicData.getDicValue(), dicData.getDicName());
                    resultMap.put(dicData.getDicGroup(), map);
                }

            }
            //--------------------------
            List<DicUnit> dicUnitList = dicUnitService.select(new DicUnit());
            Map unitMap = new HashMap();
            for (DicUnit dicUnit : dicUnitList) {

                unitMap.put(dicUnit.getCode(), dicUnit.getUnit());


            }
            resultMap.put("unit", unitMap);
            //-------------------------------

            List<DicIllness> dicIllnessList = dicIllnessService.select(new DicIllness());
            Map dicIll = new HashMap();
            for (DicIllness dicIllness : dicIllnessList) {

                dicIll.put(dicIllness.getIllcode(), dicIllness.getIllname());

            }
            resultMap.put("animalIllness", dicIll);
            //----------------------------
            List<DrugStore> drugStoreList = drugStoreService.SelectByType(2, null);
            Map drug = new HashMap();
            for (DrugStore drugStore : drugStoreList) {

                drug.put(drugStore.getNumber(), drugStore.getDrugvaccine_name());

            }
            resultMap.put("animalVaccine", drug);
            List<AnimalType> animalTypeList = animalTypeService.select(new AnimalType());
            Map one = new HashMap();
            Map two = new HashMap();
            Map three = new HashMap();
            for (AnimalType animalType : animalTypeList) {
                switch (animalType.getLevel()) {
                    case 1:

                        one.put(animalType.getAnimalCode(), animalType.getAnimalName());

                        break;
                    case 2:

                        two.put(animalType.getAnimalCode(), animalType.getAnimalName());

                        break;
                    case 3:

                        three.put(animalType.getAnimalCode(), animalType.getAnimalName());

                        break;
                }
            }

            resultMap.put("animalType", one);
            resultMap.put("animalSecondType", two);
            resultMap.put("animalThirdType", three);

            return Response.ok(resultMap);
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
            return Response.fail("获取字典错误");
        }

    }


    private List<Map> treeNode(long pid) {
        List<AnimalType> childTreeNodes = animalTypeService.queryTreeNode(pid);

        List<Map> node = null;

        if (childTreeNodes.size() > 0) {
            node = Lists.newArrayList();

            for (AnimalType animalType : childTreeNodes) {

                if (animalType.getParentId() == pid) {
                    Map<String, Object> childArray = org.apache.curator.shaded.com.google.common.collect.Maps.newHashMap();
                    childArray.put("label", animalType.getAnimalName());
                    childArray.put("value", animalType.getAnimalCode());
                    childArray.put("children", treeNode(animalType.getId()));


                    node.add(childArray);

                }


            }
        }
        return node;
    }

    /**
     * 查看个人信息
     *
     * @param userId
     * @return
     */
    @OpenMethod(key = "app.user.getUserInformation",
            paramNames = {"userId"},
            httpMethods = RequestMethod.GET

    )
    public Response<Map> getUserInformation(Long userId) {
        if (userId==null){
            return Response.fail(HttpCode.BAD_REQUEST,"用户Id为null");
        }
        MzUser mzUser = mzUserService.getMzUser(userId);
        List<OrganizationUser> list = organizationUserService.selectByUserId(userId);
        for (OrganizationUser organizationUser : list) {
            switch (organizationUser.getType()) {
                case 1:
                    String orgName = organizationService.getOrganizationById(organizationUser.getOrgId()).getName();
                    mzUser.setOrgName(orgName);
                    break;
                case 2:
                    String depName = organizationService.getOrganizationById(organizationUser.getOrgId()).getName();
                    mzUser.setDepName(depName);
                    break;
            }
        }
        List<RoleAppUser> roleAppUsers = roleAppUserService.queryRoleAppByUserId(userId);
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(userId);
        LoginUser loginUser1 = ssoLoginService.selectOne(loginUser);

        Farms farms = farmsUserService.getFarmByUserId(userId);
        if (farms != null) {
            mzUser.setFarmName(farms.getFarmsname());
        }

        Map map = new HashMap();
        map.put("mzUser", mzUser);
        map.put("RoleAppUser", roleAppUsers);
        map.put("loginUser", loginUser1);
        return Response.ok(map);
    }


    /**
     * 更新用户密码
     *
     * @param userId
     * @param passWordNew
     * @param passWordOld
     * @return
     */
    @OpenMethod(key = "app.user.updatePassword",
            paramNames = {"userId", "passWordNew", "passWordOld"},
            httpMethods = RequestMethod.POST

    )
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class, RuntimeException.class})
    public Response<Map> updatePassword(Long userId, String passWordNew, String passWordOld) {
        if (userId==null){
            return Response.fail(HttpCode.BAD_REQUEST,"用户Id为null");
        }
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(userId);
        LoginUser loginUserNew = ssoLoginService.selectOne(loginUser);
        String passWord = loginUserNew.getPassword();
        String passWord1 = MD5Util.encrypt(loginUserNew.getSalt() + passWordOld);
        if (!passWord.equals(passWord1)) {
            return Response.fail(HttpCode.DATA_UPDATE_FAIL, "原密码不对");
        }
        loginUserNew.setPassword(MD5Util.encrypt(loginUserNew.getSalt() + passWordNew));
        try {
            ssoLoginService.updateByPrimaryKeySelective(loginUserNew);
            Map map = new HashMap();
            map.put("date", "密码更新成功");
            return Response.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return Response.fail(HttpCode.DATA_UPDATE_FAIL, "密码更新失败");
        }
    }

    /**
     * 更新个人资料
     * @param mzUser
     * @return
     */
    @OpenMethod(key = "app.user.updateMzUser",
            paramNames = {"mzUser"},
            httpMethods = RequestMethod.POST

    )
    public Response<Map> updateMzUser(MzUser mzUser) {
        try {
            if (mzUser.getId()==null){
                return Response.fail(HttpCode.BAD_REQUEST,"用户Id为null");
            }
            mzUserService.updateByPrimaryKeySelective(mzUser);
            Map map = new HashMap();
            map.put("date", "更新信息成功");
            return Response.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return Response.fail(HttpCode.DATA_UPDATE_FAIL, "更新信息失败");
        }

    }
}
